import {
  makeAutoObservable,
  runInAction,
  action,
  observable,
  makeObservable,
  autorun,
  reaction,
  configure,
//   runlnAction,
} from "mobx";

// never 控制台异步警告 always 控制台同步警告 warn 控制台同步警告并抛出异常
// 默认是observed  只能在action函数中修改。 现在设置never 可以在任何函数中进行修改
configure({
    enforceActions: 'never',//"always", 
})

// 计算属性还需要通过makeAutoObservable方法指定;


// reaction的使用
// Mobx监听属性的使用
// Mobx监听属性主要有以下两种方式，现在分别对两种监听方式的使用进行讲解，如下：

// autoRun的使用

// autoRun函数接受一个函数作为参数，每当该函数所观察的值发生变化时，它都应该运行，当自己创建 autoRun 时，它也会运行一次，Mobx会自动收集并订阅所有的可观察属性，一旦有改变发生，autorun将会再次执行。


// reaction类似于autorun，但可以更加精细地控制要跟踪的可观察对象，与autorun不同，reaction在初始化时不会自动运行。
class Store {
    constructor() {
        // 参数1：target 把谁变成响应式(可观察)；参数2：指定哪些属性或方法变成可观察
        // makeObservable(this, {
        //   // 设置观察模式
        //   count: observable, // 设置管理状态的数据
        //   increment: action.bound, // 可以设置bound属性修改this指向
        //   decrement: action,
        //   reset: action,
        // });
        makeAutoObservable(this, {}, { autoBind: true });
    }
    // 当前的初始化状态数据
    count = 0;

    // 操作状态的方法
    increment() {
        // this.count++;
        setTimeout(() => {
            //异步处理    还可以使用 runlnAction 进行异步处理，通过runlnAction可以保证所有异步更新可观察对象的步骤都应该标识为action
            // runlnAction(() => {
            //     this.count++;
            // })
            //this.count++;
            runInAction(() => {
                this.count++;
            })  //runInAction可以保证所有异步更新可观察对象的步骤都应该标识为action
            //runInAction可以保证所有异步更新可观察对象的步骤都应该标识为action
            
        },1000)
    }
    decrement() {
        this.count--;
    }
    reset() {
        this.count = 0;
    }
}
const store = new Store();
// 监听数据的变化
autorun(() => {
    console.log("counter.count", store.count);
});
// 监听数据的变化
// reaction接收两个参数，参数1：data函数，其返回值会作为第二个函数的输入；参数2：回调函数
reaction(
  () => store.count,
  (value, oldvalue) => {
    console.log("count数据发生变化了", value, oldvalue);
  }
);
export default store;